package org.etom.impl.ui.util;

import java.io.File;
import java.util.StringTokenizer;

import org.etom.connector.datatypes.IMoodleConnection;
import org.etom.connector.datatypes.IMoodleCourse;
import org.etom.connector.datatypes.IMoodleModule;

/**
 * The utility class which cares about
 * the common tasks.
 */
public class Utility {

  private static final char REF_NAME_OPEN    = '[';
  private static final char REF_NAME_CLOSE   = ']';
  private static final String EMPTY_STRING   = ""; //$NON-NLS-1$
  private static final String CHAR_DELIM     = ","; //$NON-NLS-1$
  private static final char[] ENCRYPTION_KEY =
  {'E', 't', 'o', 'M', '_', 'K', 'e', 'y'};
  
  /**
   * @param connection
   * @return the string representation of the connection
   */
  public static String toString(IMoodleConnection connection) {
    return (connection == null) ? EMPTY_STRING :
      connection.getUserName() + '@' + connection.getMoodleUrl() + connection.getRpcServerUrl();
  }
  
  /**
   * @param course
   * @return the string representation of the course
   */
  public static String toString(IMoodleCourse course) {
    return (course == null) ? EMPTY_STRING :
      course.getFullName();
  }
  
  /**
   * @param module
   * @return the string representation of the module
   */
  public static String toString(IMoodleModule module) {
    if (module == null) return EMPTY_STRING;
    String moduleName = module.getName();
    String referenceName = module.getReferenceName();
    StringBuffer result = new StringBuffer();
    if (moduleName != null) result.append(moduleName);
    else result.append(CommonMessages.Missing_Module_Name);
    if ((referenceName != null) &&
        (referenceName.trim().length() != 0)) {
      result.append(REF_NAME_OPEN);
      result.append(referenceName);
      result.append(REF_NAME_CLOSE);
    }
    return result.toString();
  }
  
  /**
   * The utility method which deletes the directory and its content.
   * @param dir - the directory which will be deleted
   * @param deleteParent - if <code>false</code> - delete only content
   * @return <code>true</code> if the directory is deleted successfully,
   *         <code>false</code> otherwise
   */
  public static boolean deleteDir(File dir, boolean deleteParent) {
    if ((null == dir) || (!dir.exists())) return true;
    if (dir.isFile()) return dir.delete();
    File[] children = dir.listFiles();
    for (File child : children) {
      if (!deleteDir(child, true)) return false;
    }
    if (deleteParent) return dir.delete();
    else return true;
  }
  
  /**
   * The method encrypts the given password.
   * 
   * @param password - the password in plain format
   * 
   * @return - encrypted password
   */
  public static String encrypt(String password) {
    if (password == null) return null;
    StringBuffer result = new StringBuffer();
    for (int i = 0; i < password.length(); i++) {
      result.append(crypt(((int)password.charAt(i)), i));
      result.append(CHAR_DELIM);
    }
    result.deleteCharAt(result.length() - 1);
    return result.toString();
  }
  
  /**
   * The method decrypts the given password.
   * 
   * @param password - the password in encrypted format
   * 
   * @return - decrypted password
   */
  public static String decrypt(String password) {
    StringTokenizer passwordTokens = new StringTokenizer(password, CHAR_DELIM);
    String nextToken;
    StringBuffer result = new StringBuffer();
    int currentCharCode;
    int i = 0;
    while (passwordTokens.hasMoreTokens()) {
      nextToken = passwordTokens.nextToken();
      currentCharCode = Integer.parseInt(nextToken);
      result.append((char) crypt(currentCharCode, i));
      i++;
    }
    return result.toString();
  }
  
  /*
   * An utility method which encrypts/decrypts a single char.
   */
  private static int crypt(int charCode, int keyIndex) {
    return (charCode ^ ENCRYPTION_KEY[keyIndex % ENCRYPTION_KEY.length]);
  }
  
}
